package com.chenfan.mcn.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.annotations.ActionTracing;
import com.chenfan.mcn.annotations.NoLogin;
import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.mcn.component.MicroServiceFacade;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.dto.ExcutionOrderSearchDTO;
import com.chenfan.mcn.model.rpc.*;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.service.*;
import com.chenfan.mcn.utils.BusinessAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * MCN对外提供微服务接口
 *
 * @author wulg
 * @date 2021-09-14
 **/
@Slf4j
@RestController
public class MicroServiceController {

    @Autowired
    private MicroServiceFacade microServiceFacade;

    @Autowired
    private IncomeContractService incomeContractService;

    @Autowired
    private ContractExcutionOrderService contractExcutionOrderService;

    @Autowired
    private AnnualRebateApprovalService annualRebateApprovalService;

    @Autowired
    private StarBasicDataService starBasicDataService;

    @Autowired
    private StarMonthlySettlementService settlementService;

    @Autowired
    private StarAccountInfoService starAccountInfoService;

    @Autowired
    private StarBillingHeaderService starBillingHeaderService;


    /**
     * 财务结算单的执行单信息（新：费用使用）
     * @param chargeType 费用类型
     * @param chargeSourceCode 来源单号
     * @return
     */
    @GetMapping("/excutionOrder/settleInfoForCharge")
    public Res<ExcutionSettleInfoVO> getSettleInfoForCharge(@RequestParam Integer chargeType, @RequestParam String chargeSourceCode) {
        return Res.ok(contractExcutionOrderService.getSettleInfoForCharge(chargeType, chargeSourceCode));
    }

    /**
     * 执行单编号查询执行单打款信息详情
     *
     * @param excuteCode 执行单号
     * @return
     */
    @Deprecated
    @GetMapping("/excutionOrder/paid/excute/code")
    public Res<PaidInfoDetailVO> detailPaidInfoOfCode(@RequestParam String excuteCode) {
        return Res.ok(contractExcutionOrderService.detailPaidInfoOfCode(excuteCode));
    }

    /**
     * 根据子结算单号查询打款信息详情（默认）
     * @param subSettlementCode
     * @return
     */
    @GetMapping("/starMonthlySettlement/paidInfo/getDefaultByCode")
    public Res<PaidInfoDetailVO> getDefaultPaidInfoByCode(@RequestParam String subSettlementCode) {
        BusinessAssert.notBlank(subSettlementCode, McnErrorCode.PARAM_ERROR, "子结算单号不能为空");
        return Res.ok(settlementService.getDefaultPaidInfoByCode(subSettlementCode));
    }


    /**
     * chenfan-baseinfo
     * 获取已关联收入合同
     *
     * @param billingId {@link Long}
     * @return {@link List<Long>}
     */
    @GetMapping("/incomeContract/getRelatedIncomeContract")
    public Res<List<Long>> getRelatedIncomeContract(Long billingId) {
        return Res.ok(incomeContractService.getRelatedIncomeContract(billingId));
    }


    /**
     * 按业务场景统一处理财务回调接口
     * @param request
     * @return
     */
    @ActionTracing(value = "财务回调", allAlarm = true)
    @NoLogin
    @PostMapping("/finance/callback")
    public Res<Object> financeCallback(@Validated @RequestBody(required = false) AbstractFinanceCallback request) {
        BusinessAssert.notNull(request, McnErrorCode.PARAM_ERROR, "财务回调场景码不能为空");
        log.info("收到财务回调请求！报文：{}", JSONObject.toJSONString(request));
        if(request instanceof ChargeClearCallback) {
            return Res.ok(microServiceFacade.clearPaybackCallback((ChargeClearCallback)request));
        } else if(request instanceof BatchChargeClearCallback) {
            return Res.ok(microServiceFacade.batchClearPaybackCallback((BatchChargeClearCallback)request));
        } else if(request instanceof InvoicedCallback) {
            //下架，改走实时查询
            return Res.ok(Boolean.TRUE);
        } else if(request instanceof BatchInvoicedCallback) {
            //下架，改走实时查询
            return Res.ok(Boolean.TRUE);
        } else if(request instanceof ExcutionOrderChangePaidCallback) {
            ExcutionOrderChangePaidCallback changePaidCallback = (ExcutionOrderChangePaidCallback)request;
            //没用了
            return Res.ok(Boolean.TRUE);
        } else if(request instanceof ExcutionOrderPaidCallback) {
            ExcutionOrderPaidCallback paidCallback = (ExcutionOrderPaidCallback)request;
            return Res.ok(contractExcutionOrderService.setPaid(paidCallback));
        } else if(request instanceof ChangeAnnualRebateStatusCallback) {
            ChangeAnnualRebateStatusCallback statusCallback = (ChangeAnnualRebateStatusCallback)request;
            annualRebateApprovalService.financeStatusChange(statusCallback, UserVoContextHolder.getUserVo(McnErrorCode.USER_INFO_ERROR));
            return Res.ok(Boolean.TRUE);
        }
        throw new BusinessException(McnErrorCode.PARAM_ERROR.code(), "请正确标记财务回调场景码！");
    }

    /**
     * 红人资料详情
     *
     * @param starId 请求参数
     * @return 返回值
     */
    @GetMapping(value = "/star/getInfoById", produces = {"application/json;charset=UTF-8"})
    public Res<StarBasicDataInfoVO> getStarInfoById(@RequestParam Long starId) {
        return Res.ok(starBasicDataService.info(starId));
    }


    /**
     * 红人月度结算单打印调用
     */
    @GetMapping(value = {"/starMonthlySettlement/starMonthlySettlementPrint"})
    public Res<StarMonthlySettlementPrintVO> getStarMonthlySettlementPrint(@RequestParam String subSettlementCode) {
        BusinessAssert.notNull(subSettlementCode, McnErrorCode.PARAM_ERROR, "子结算单号不能为空");
        return Res.ok(settlementService.getStarMonthlySettlementPrint(subSettlementCode));
    }

    /**
     * 批量根据红人ID集合获取红人昵称
     * @param starIds
     * @return
     */
    @PostMapping("/star/basic/getStarNickNamesByIds")
    public Res<List<StarNickNameVO>> getStarNickNamesByIds(@RequestBody List<Long> starIds) {
        BusinessAssert.notNull(starIds, McnErrorCode.PARAM_ERROR, "红人ID集合不能为空");
        return Res.ok(starBasicDataService.getStarNickNamesByIds(starIds));
    }


    /**
     * 根据红人账号id获取红人收款账户信息
     * @param starAccountId
     * @return
     */
    @GetMapping("/star/account/getById")
    public Res<StarAccountInfo> getStarAccountById(@RequestParam Long starAccountId) {
        return Res.ok(starAccountInfoService.getById(starAccountId));
    }

    /**
     * 根据红人开票id获取红人开票信息
     * @param starBillingId
     * @return
     */
    @GetMapping("/star/billing/getById")
    public Res<StarBillingHeader> getStarBillingById(@RequestParam Long starBillingId) {
        return Res.ok(starBillingHeaderService.selectById(starBillingId));
    }

    /**
     * 根据红人姓名获取红人收款账户信息
     * @param starName
     * @return
     */
    @GetMapping("/star/account/getByName")
    public Res<StarAccountInfo> getStarAccountByName(@RequestParam String starName) {
        return Res.ok(starAccountInfoService.getByName(starName));
    }

    /**
     * 获取所有红人财务信息、开票信息
     * @return
     */
    @GetMapping("/star/allAccountInfo")
    public Res<List<StarAccountOrBillingInfoResp>> allAccountInfo(@RequestParam(required = false) Integer starStatus) {
        return Res.ok(starAccountInfoService.allAccountInfo(starStatus));
    }

    /**
     *  根据红人id获取红人收款账户信息集合
     * @param starId
     * @return
     */
    @GetMapping("/star/account/getListByStarId")
    public Res<List<StarAccountInfo>> getListByStarId(@RequestParam Long starId) {
        return Res.ok(starAccountInfoService.getListByStarId(starId));
    }

    /**
     *  根据来源单号获取直播红人结算单最新流程ID
     * @param sourceBillCode
     * @return
     */
    @GetMapping("/liveStarSettlement/getNewFlowId")
    public Res<Long> getNewFlowIdOfLiveStarSettlement(@RequestParam(defaultValue = "") String sourceBillCode) {
        BusinessAssert.notBlank(sourceBillCode, McnErrorCode.PARAM_ERROR, "来源单号不能为空");
        return Res.ok(microServiceFacade.getNewFlowIdOfLiveStarSettlement(sourceBillCode));
    }

    /**
     * 通过执行单编号获取财务执行单信息
     * @param excuteCodes 执行单号（数组）
     * @return
     */
    @PostMapping("/excutionOrder/getFinanceExcutionOrderByCodes")
    public Res<List<FinanceExcutionOrderVO>> getFinanceExcutionOrderByCodes(@RequestBody List<String> excuteCodes) {
        BusinessAssert.notEmpty(excuteCodes, McnErrorCode.PARAM_ERROR, "执行单编号不能为空");
        return Res.ok(contractExcutionOrderService.getFinanceExcutionOrderByCodes(excuteCodes));
    }

    /**
     *
     * @param excutionOrderSearchDTO
     * @return
     */
    @PostMapping("/excutionOrder/page/rpc")
    public Res<Page<ExcutionOrderVO>> getPageRpc(@RequestBody ExcutionOrderSearchDTO excutionOrderSearchDTO) {
        return Res.ok(contractExcutionOrderService.getPage(new McnPage<>(), excutionOrderSearchDTO));
    }
}
